#include "readwritefile.h"
#include <fstream>
#include "print.h"

template <typename... Args>
void print_error(Args &&...args)
{
    chainsaw::print_class_error("readwritefile", std::forward<Args>(args)...);
}

bool chainsaw::is_exists(const std::string &name)
{
    return std::filesystem::exists(name);
    // c11
    // return std::ifstream(name.c_str()).good();
}

bool chainsaw::is_file(std::string const &file_name)
{
    return std::filesystem::is_regular_file(file_name);
}

bool chainsaw::is_path(std::string const &path_name)
{
    return std::filesystem::is_directory(path_name);
}

std::vector<std::string> chainsaw::read_file(std::string const &file_name, bool keep_empty_lines)
{
    std::vector<std::string> lines;
    if (!is_file(file_name))
        return lines;

    std::ifstream fin(file_name);

    if (!fin.is_open())
    {
        print_error("Failed to open file: " + file_name);
    }

    std::string line;
    while (std::getline(fin, line))
    {
        if (!keep_empty_lines && line.empty())
            continue;
        lines.push_back(line);
    }

    return lines;
}

chainsaw::write_file::write_file(const std::string &file, WriteMode mode)
{
    if (mode == WriteMode::CreateNew && is_exists(file))
    {
        print_error("the file is exists!->[", file, "]", "write_file");
    }

    std::ios::openmode open_mode = std::ios::out;

    if (mode == WriteMode::Append)
        open_mode |= std::ios::app;
    else
        open_mode |= std::ios::trunc; // overwrite

    m_stream.open(file, open_mode);

    if (!m_stream)
    {
        print_error("Failed to open file: ", file);
    }
}

void chainsaw::write_file::write(std::string const &data, bool line)
{
    m_stream << data;
    if (line)
        m_stream << std::endl;
}

void chainsaw::write_file::write(std::vector<std::string> data)
{
    for (std::string s : data)
    {
        write(s);
    }
}

chainsaw::write_file::~write_file()
{
    if (m_stream.is_open())
        m_stream.close();
}
